package com.zipou.framework.persistence;

import java.io.Serializable;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.NoResultException;
import javax.persistence.Query;


public class MyDao <T extends Serializable> {

	private Class<T> domainClass;

	//@Inject
	private EntityManager em = MyEntityManagerFactory.createEntityManager();

	public MyDao(Class<T> cl) {
		domainClass = cl;
	}

	public final T getElementById(String id) throws NoResultException {
		String queryStr = "select d  FROM " + domainClass.getSimpleName() + " d  WHERE id = '"+ id +"'";
		Query query = em.createQuery(queryStr);

		Object o = query.getSingleResult();
		T obj = domainClass.cast(o);

		return obj;
	}

	/*
	 * TODO
	 * Gerer la consommation de cette methode
	 */
	/*
	 * @Deprecated
	 * @See #getElementListByHql
	 */
	@SuppressWarnings("unchecked")
	@Deprecated
	public final List<T> getElementListBySql(String sql) {
		Query query = em.createNativeQuery(sql, domainClass);
		//		List<T> returnList = (List<T>) query.getResultList();
		return (List<T>) query.getResultList();
	}

	@SuppressWarnings("unchecked")
	public final List<T> getElementListByHql(String hql) {
		Query query = em.createQuery(hql);
		return (List<T>) query.getResultList();
	}

	public final List<T> getElementList() {
		return getElementList(null, null, true, -1, -1);
	}

	public final int getCount(List<String> params) {
		String q = "select COUNT(s) FROM " + domainClass.getSimpleName()  + " s ";
		if ((params != null) && (params.size() >= 1)) {
			q = q + " WHERE ";
			int i = 0;
			for (String s : params) {
				if (i>=1) { 
					q = q.concat(" AND ").concat(s);
				} else {
					q = q.concat(s);
				}
				i++;
			}
		}

		Query query = em.createQuery(q);
		return Integer.decode(query.getSingleResult().toString());	
	}

	public final List<T> getElementList(List<String> params) {
		return getElementList(params, null, true, -1, -1);
	}

	public final List<T> getElementList(List<String> params, String order) {
		return getElementList(params, order, true, -1, -1);
	}	

	public final List<T> getElementList(List<String> params, String order, Integer first, Integer max) {
		return getElementList(params, order, true, first, max);
	}	


	@SuppressWarnings("unchecked")
	public final List<T> getElementList(List<String> params, String order, boolean inclusif, int first, int max) {
		String q = "select s FROM " + domainClass.getSimpleName()  + " s ";
		String agreg = " AND ";
		if (! inclusif) {
			agreg = " OR ";
		}

		if ((params != null) && (params.size() >= 1)) {
			q = q + " WHERE ";
			int i = 0;
			for (String s : params) {
				if (i>=1) { 
					q = q.concat(agreg).concat(s);
				} else {
					q = q.concat(s);
				}
				i++;
			}
		}

		if (order != null) {
			q += " ORDER BY " + order;
		}

		Query query = em.createQuery(q);
		if (first >= 0) query.setFirstResult(first);
		if (max >=0) query.setMaxResults(max);
		return (List<T>) query.getResultList();
	}

	public final void EmptyTable() {
		String q = "delete FROM " + domainClass.getSimpleName();
		em.createQuery(q);

	}

	public final void delete(T o) {
		EntityTransaction tx = em.getTransaction();
		try {
			tx.begin();
			em.remove(o);
			tx.commit();
		}
		finally
		{
			if (tx.isActive())
			{
				tx.rollback();
			}
		}
	}

	public final void save(T o) {
		EntityTransaction tx = em.getTransaction();
		try {
			tx.begin();
			em.persist(o);
			tx.commit();
		}
		finally
		{
			if (tx.isActive())
			{
				tx.rollback();
			}
		}
	}

}